home *** CD-ROM | disk | FTP | other *** search
/ LiquidLibrary 2005 February / LiquidLibrary 2005 February - Disc 1.iso / pc / Portfolio Browser / Filters / PDF / LIB / gs_cff.ps < prev    next >
Text File  |  2003-01-03  |  22KB  |  748 lines

  1. %    Copyright (C) 1997, 1998, 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is licensed to a single customer by Artifex Software Inc.
  3. % under the terms of a specific OEM agreement.
  4.  
  5. % $RCSfile$ $Revision$
  6. % Loader for CFF (compressed) fonts, including OpenType CFFs.
  7. % The following are not implemented yet:
  8. %    Deleted entries in the Name Index
  9. %    Embedded PostScript
  10. %    Multiple Master fonts
  11. %    Chameleon fonts
  12. %    Synthetic fonts
  13.  
  14. % ---------------- Font loading machinery ---------------- %
  15.  
  16. % Augment the FONTPATH machinery so it recognizes OpenType CFF font sets.
  17.  
  18. /.scanfontheaders where {
  19.   pop /.scanfontheaders [
  20.    .scanfontheaders aload pop (OTTO*)
  21.   ] def
  22. } if
  23.  
  24. % Load a font file that might be an OpenType CFF font set.
  25.  
  26. % <file> .loadfontfile -
  27. /.loadnonottofontfile /.loadfontfile load def
  28. /.loadfontfile {
  29.   dup 4 string .peekstring pop (OTTO) eq {
  30.         % If this is a font at all, it's an OpenType CFF font set.
  31.     .loadottofontfile
  32.   } {
  33.         % Not a TrueType font.
  34.     .loadnonottofontfile
  35.   } ifelse
  36. } bind def
  37.  
  38. % <file> .loadottofontfile -
  39. /.loadottofontfile {
  40.   /FontSetInit /ProcSet findresource begin
  41.   2 dict begin
  42.   /f exch def /cff null def
  43.   card32 pop card16 6 { next pop } repeat dup {
  44.         % Stack: numtables tablesleft
  45.     dup 0 eq {
  46.       pop pop /.loadottofontfile cvx /invalidfont signalerror
  47.     } if
  48.     f 4 string readstring pop (CFF ) eq { sub exit } if
  49.     1 sub
  50.   } loop
  51.         % Stack: tablesread
  52.   card32 pop card32 card32
  53.         % Stack: tablesread start length
  54.   exch 3 -1 roll 1 add 16 mul 12 add sub
  55.   f exch subfilefilter flushfile    % skip to start
  56.   f exch subfilefilter end
  57.     % Use a random FontSet resource name.  ****** WRONG ******
  58.   realtime rand xor =string cvs exch false
  59.   ReadData
  60. } bind def
  61.  
  62. 30 dict begin
  63.  
  64. % ---------------- Standard strings (actually names) ---------------- %
  65.  
  66. /StandardStrings mark
  67.     % The initial StandardStrings that that denote characters are
  68.     % defined as a pseudo-Encoding.
  69. % 0
  70.   /CFFStandardStrings .findencoding aload pop
  71. % 379
  72.   (001.000)
  73. % 380
  74.   (001.001) (001.002) (001.003) /Black /Bold
  75.   /Book /Light /Medium /Regular /Roman
  76.   /Semibold
  77. .packtomark def
  78.  
  79. % ---------------- Standard encodings ---------------- %
  80.  
  81. /StandardEncodings [
  82.  
  83. % StandardEncoding
  84. mark
  85.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  86.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  87.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  88.   17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
  89.   33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
  90.   49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
  91.   65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
  92.   81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 0
  93.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  94.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  95.   0 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
  96.   0 111 112 113 114 0 115 116 117 118 119 120 121 122 0 123
  97.   0 124 125 126 127 128 129 130 131 0 132 133 0 134 135 136
  98.   137 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  99.   0 138 0 139 0 0 0 0 140 141 142 143 0 0 0 0
  100.   0 144 0 0 0 145 0 0 146 147 148 149 0 0 0 0
  101. .packtomark
  102.  
  103. % ExpertEncoding
  104. mark
  105.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  106.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  107.   1 229 230 0 231 232 233 234 235 236 237 238 13 14 15 99
  108.   239 240 241 242 243 244 245 246 247 248 27 28 249 250 251 252
  109.   0 253 254 255 256 257 0 0 0 258 0 0 259 260 261 262
  110.   0 0 263 264 265 0 266 109 110 267 268 269 0 270 271 272
  111.   273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  112.   289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 0
  113.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  114.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  115.   0 304 305 306 0 0 307 308 309 310 311 0 312 0 0 313
  116.   0 0 314 315 0 0 316 317 318 0 0 0 158 155 163 319
  117.   320 321 322 323 324 325 0 0 326 150 164 169 327 328 329 330
  118.   331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
  119.   347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
  120.   363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
  121. .packtomark
  122.  
  123. ] readonly def
  124.  
  125. % ---------------- Standard Charsets ---------------- %
  126.  
  127. % We include an explicit 0 at the beginning of each charset.
  128.  
  129. /StandardCharsets [
  130.  
  131. % ISOAdobe
  132. mark
  133.   0
  134.   1 1 228 { } for
  135. .packtomark
  136.  
  137. % Expert
  138. mark
  139.   0
  140.   1 229 230 231 232 233 234 235 236 237 238 13 14 15 99 239
  141.   240 241 242 243 244 245 246 247 248 27 28 249 250 251 252 253
  142.   254 255 256 257 258 259 260 261 262 263 264 265 266 109 110 267
  143.   268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
  144.   284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
  145.   300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
  146.   316 317 318 158 155 163 319 320 321 322 323 324 325 326 150 164
  147.   169 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
  148.   342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
  149.   358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
  150.   374 375 376 377 378
  151. .packtomark
  152.  
  153. % ExpertSubset
  154. mark
  155.   0
  156.   1 231 232 235 236 237 238 13 14 15 99 239 240 241 242 243
  157.   244 245 246 247 248 27 28 249 250 251 253 254 255 256 257 258
  158.   259 260 261 262 263 264 265 266 109 110 267 268 269 270 272 300
  159.   301 302 305 314 315 158 155 163 320 321 322 323 324 325 326 150
  160.   164 169 327 328 329 330 331 332 333 334 335 336 337 338 339 340
  161.   341 342 343 344 345 346
  162. .packtomark
  163.  
  164. ] readonly def
  165.  
  166. % ---------------- Font loading ---------------- %
  167.  
  168. % ------ Utilities ------ %
  169.  
  170. /advance {    % <n> advance -
  171.   f cff eq { pos add /pos exch store } { pop } ifelse
  172. } bind def
  173. /next {        % - next <byte>
  174.   f read {
  175.     1 advance
  176.     DEBUG { (  ) print dup = } if
  177.   } if
  178. } bind def
  179. /next2 {    % - next2 <byte1> <byte2>
  180.   f read {
  181.     f read {
  182.       2 advance
  183.       DEBUG { (  ) print 1 index =only (,) print dup = } if
  184.     } {
  185.       1 advance
  186.       DEBUG { (  ) print dup = } if
  187.     } ifelse
  188.   } if
  189. } bind def
  190. /nextstring {    % <length> nextstring <string>
  191.   dup 0 eq {
  192.     pop ()
  193.   } {
  194.     string f exch readstring pop dup length advance
  195.     DEBUG { (  ) print dup == } if
  196.   } ifelse
  197. } bind def
  198. /card8        % - card8 <card8>
  199.  /next load
  200. def
  201. /card16 {    % - card16 <card16>
  202.   next2 exch 8 bitshift add
  203. } bind def
  204. /card32 {    % - card32 <card32>
  205.   card16 16 bitshift card16 add
  206. } bind def
  207. /offsetprocs [
  208.   /card8 load
  209.   /card16 load
  210.   { card8 16 bitshift card16 add } bind
  211.   /card32 load
  212. ] readonly def
  213. /offsetproc {    % <offsize> offsetproc <proc>
  214.   1 sub //offsetprocs exch get
  215. } bind def
  216. /offset {    % <offsize> offset <offset>
  217.   offsetproc exec
  218. } bind def
  219. /sid        % - <sid> sid
  220.   /card16 load
  221. def
  222. /Index {    % - Index <array>
  223.   mark card16 dup 0 ne {
  224.     1 exch next offsetproc dup exec pop exch {
  225.       dup exec dup 4 -1 roll sub 3 1 roll exch
  226.     } repeat pop
  227.   } if pop .packtomark
  228.   [ exch { nextstring } forall ] readonly
  229. } bind def
  230. /tokens {    % - tokens <num1> ... <op#> (op# = 12 means EOF)
  231.   {
  232.     f read not { 12 exit } if
  233.     DEBUG { (..) print dup = } if
  234.     1 advance
  235.     dup 12 eq { pop next 32 add exit } if
  236.     dup 28 lt { exit } if
  237.     dup 32 lt {
  238.       28 sub {
  239.     { card16 32768 xor 32768 sub }
  240.     { 4 offset dup 16#7fffffff gt { -1 32 bitshift add } if }
  241.     { tokenreal }
  242.     { 31 exit }
  243.       } exch get exec
  244.     } {
  245.       dup 247 lt {
  246.     139 sub
  247.       } {
  248.     247 sub {
  249.       { next 108 add }
  250.       { next 364 add }
  251.       { next 620 add }
  252.       { next 876 add }
  253.       { next 108 add neg }
  254.       { next 364 add neg }
  255.       { next 620 add neg }
  256.       { next 876 add neg }
  257.       % 255 is deliberately omitted and will cause a rangecheck
  258.     } exch get exec
  259.       } ifelse
  260.     } ifelse
  261.   } loop
  262. } bind def
  263. /tokenbuf 100 string def
  264. /tokenput {    % <index> <char> tokenput <index+1>
  265.   tokenbuf 2 index 3 -1 roll put 1 add
  266. } bind def
  267. /tokenrealarray [
  268.  (0123456789.E) { } forall
  269.  [(E) 0 get /tokenput cvx (-) 0 get] cvx
  270.  null        % will give an error
  271.  (-) 0 get
  272.  { exit }
  273. ] readonly def
  274. /tokenreal {    % - tokenreal <float>
  275.   0 {
  276.     next exch 1 index -4 bitshift tokenrealarray exch get exec tokenput
  277.         % We must leave the byte on the stack temporarily so that
  278.         % the exit will see a consistent stack state.
  279.     1 index 15 and tokenrealarray exch get exec tokenput exch pop
  280.   } loop
  281.   tokenbuf 0 3 -1 roll getinterval cvr exch pop
  282. } bind def
  283. /Dict {        % <opsdict> Dict -
  284.   /opdict exch store {
  285.     mark tokens
  286.     DEBUG { (tokens: ) print ] dup === mark exch aload pop } if
  287.     opdict exch .knownget { exec } if cleartomark
  288.   } loop cleartomark
  289. } bind def
  290. /idstring {    % <sid> idstring <string|name>
  291.   dup 391 lt { //StandardStrings } { 391 sub strings } ifelse exch get
  292. } bind def
  293. /idname {    % <sid> idname <name>
  294.   idstring dup type /nametype ne { cvn } if
  295. } bind def
  296. /subfilefilter {    % <file> <length> subfilefilter <filter>
  297.     % SubFileDecode interprets a length of 0 as infinite.
  298.   dup 0 le { pop pop () 0 } if () /SubFileDecode filter
  299. } bind def
  300.  
  301. % ------ Top dictionary ------ %
  302.  
  303. /offput {    % <offset> <proc> offput -
  304.   DEBUG { (queued: ) print 1 index =only ( ) print dup === } if
  305.   currentdict exch aload length 1 add packedarray cvx
  306.   offsets 3 1 roll put
  307. } bind def
  308. /queueput {    % <font> <proc> queueput -
  309.   16#7fffffff offsets { pop .min } forall
  310.   pos sub nextstring
  311.   3 1 roll aload length 2 add packedarray cvx
  312.   [ queued aload pop counttomark 2 add -1 roll ]
  313.   /queued exch store
  314. } bind def
  315. /xxput {    % <value> <key> <dict> xxput -
  316.   3 1 roll exch put
  317. } bind def
  318. /putfi {    % <value> <key> putfi -
  319.   FontInfo xxput
  320. } bind def
  321. /xdef {        % <value> <key> xdef -
  322.   exch def
  323. } bind def
  324. /topdictops mark
  325.   12 { exit }
  326.   0 { idstring /version putfi }
  327.   1 { idstring /Notice putfi }
  328.   32 { idstring /Copyright putfi }
  329.   2 { idstring /FullName putfi }
  330.   3 { idstring /FamilyName putfi }
  331.   4 { idstring /Weight putfi }
  332.   33 { 0 ne /isFixedPitch putfi }
  333.   34 { /ItalicAngle putfi }
  334.   35 { /UnderlinePosition putfi }
  335.   36 { /UnderlineThickness putfi }
  336.   37 { /PaintType xdef }
  337.   38 { /FontType xdef }        % actually CharstringType
  338.   39 { counttomark array astore /FontMatrix xdef }
  339.   13 { /UniqueID xdef }
  340.   5 { counttomark array astore /FontBBox xdef }
  341.   40 { /StrokeWidth xdef }
  342.   14 { counttomark array astore /XUID xdef }
  343.   15 {
  344.     dup StandardCharsets length lt {
  345.       StandardCharsets exch get /charset xdef
  346.     } {
  347.       { queuecharset } offput
  348.     } ifelse
  349.   }
  350.   16 {
  351.     dup StandardEncodings length lt {
  352.       /Encoding xdef
  353.     } {
  354.       { queueEncoding } offput
  355.     } ifelse
  356.   }
  357.   17 { { readCharStrings } offput }
  358.   18 { exch /readPrivate cvx 2 packedarray offput }
  359.     % CIDFont operators
  360.   62 {        % ROS, must be first in a CIDFont
  361.     currentdict /FontType undef
  362.     currentdict /Encoding undef
  363.     currentdict /FontMatrix undef
  364.     /CIDFontVersion 0 def
  365.     /CIDFontRevision 0 def
  366.     /CIDFontType 0 def
  367.     /CIDCount 8720 def % Default value defined in CFF spec.
  368.     3 dict begin
  369.     /Supplement xdef
  370.     idstring /Ordering xdef
  371.     idstring /Registry xdef
  372.     /CIDSystemInfo currentdict end def
  373.   }
  374.   63 { /CIDFontVersion xdef }
  375.   64 { /CIDFontRevision xdef }
  376.   65 { /CIDFontType xdef }
  377.   66 { /CIDCount xdef }
  378.   67 { /UIDBase xdef }
  379.   68 { { readFDArray } offput }
  380.   69 { { readFDSelect } offput }
  381.     % This operator only appears in a FDArray element.
  382.   70 { idstring /FontName exch def }
  383. .dicttomark readonly def
  384.  
  385. % readcharset and readFDSelect may require the length of CharStringArray,
  386. % but these structures may occur in the file before the CharStrings.
  387. % If that happens, use a hack: assume that all the data up to the next
  388. % queued read should be read.
  389.  
  390. /charstringcount {    % <font> charstringcount <count> true
  391.             % <font> charstringcount <length> false
  392.   /CharStringArray .knownget {
  393.     length true
  394.   } {
  395.     % Hack: look for the next queued read.
  396.     16#7fffffff offsets { pop .min } forall
  397.     pos sub false
  398.   } ifelse
  399. } bind def
  400.  
  401. /readCharStrings {    % <font> readCharStrings -
  402.   /CharStringArray Index put
  403. } bind def
  404.  
  405. % ------ Charsets and encodings ------ %
  406.  
  407. % Note: formats 1 and 2 can overflow the operand stack.
  408. % We'll fix this if it ever becomes necessary.
  409. /charsetcount {
  410.   charstringcount { 1 sub } { 2 idiv } ifelse
  411. } bind def
  412. /charsetformats [
  413. { [ 0 3 -1 roll charsetcount { sid } repeat ]
  414. } bind
  415. { [ 0 3 -1 roll charsetcount {
  416.     dup 0 eq { pop exit } if
  417.     sid card8 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
  418.   } loop ]
  419. } bind
  420. { [ 0 3 -1 roll charsetcount {
  421.     dup 0 eq { pop exit } if
  422.     sid card16 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
  423.   } loop ]
  424. } bind
  425. ] readonly def
  426. /queuecharset {        % <font> queuecharset -
  427.   { readcharset } queueput
  428. } bind def
  429. /readcharset {        % <data> <font> readcharset -
  430.   begin 0 () /SubFileDecode filter /f exch store
  431.   charsetformats next get currentdict exch exec /charset exch def end
  432. } bind def
  433.  
  434. /encodingformats [
  435. { 1 1 next { next exch Encoding 3 1 roll put } for
  436. } bind
  437. { 1 next {
  438.     next next 1 add {
  439.             % Stack: gid code
  440.       Encoding 1 index 3 index put
  441.       exch 1 add exch 1 add
  442.     } repeat pop
  443.   } repeat pop
  444. } bind
  445. ] readonly def
  446. /queueEncoding {    % <font> queueEncoding -
  447.   { readEncoding } queueput
  448. } bind def
  449. /readEncoding {        % <data> <font> readEncoding -
  450.   begin 0 () /SubFileDecode filter /f exch store
  451.   /Encoding [ 256 { /.notdef } repeat ] def
  452.   next encodingformats 1 index 127 and get exec
  453.   128 ge {
  454.             % Read supplementary encodings.
  455.     next {
  456.       Encoding next sid idname put
  457.     } repeat
  458.   } if end
  459. } bind def
  460.  
  461. % ------ FDArray and FDSelect ------ %
  462.  
  463. /readFDArray {        % <font> readFDArray -
  464.   Index exch
  465.   2 dict begin /f null def begin
  466.   [ exch {
  467.     dup length subfilefilter /f exch store
  468.     10 dict begin
  469.     /FontType 2 def
  470.     /PaintType 0 def
  471.     /FontMatrix [0.001 0 0 0.001 0 0] def
  472.     /Private 20 dict def
  473.     //topdictops Dict currentdict end
  474.   } forall ] /FDArray xdef end end
  475. } bind def
  476.  
  477. % Note: this implementation can overflow the operand stack.
  478. % We'll fix this if it ever becomes necessary.
  479. /fdselectformats [
  480. { [ exch charstringcount pop { card8 } repeat ] } bind
  481. { /FDSelect cvx /invalidfont signalerror } bind
  482. dup
  483. { pop [ card16 card16 exch {
  484.         % Stack: previndex
  485.     card8 card16 dup 4 1 roll 3 -1 roll sub 1 sub {
  486.       exch 1 index
  487.     } repeat exch
  488.   } repeat pop ]
  489. } bind
  490. ] readonly def
  491.  
  492. /readFDSelect {        % <font> readFDSelect -
  493.   begin fdselectformats next get currentdict exch exec /FDSelect exch def end
  494. } bind def
  495.  
  496.  
  497. % ------ Private dictionary ------ %
  498.  
  499. /deltarray {        % -mark- <num1> ... deltarray <num1'> ...
  500.   0 counttomark 1 sub { counttomark -1 roll add dup } repeat pop
  501.   counttomark array astore
  502. } bind def
  503.  
  504. /privatedictops mark
  505.   12 { exit }
  506.   6 { deltarray /BlueValues xdef }
  507.   7 { deltarray /OtherBlues xdef }
  508.   8 { deltarray /FamilyBlues xdef }
  509.   9 { deltarray /FamilyOtherBlues xdef }
  510.   41 { /BlueScale xdef }
  511.   42 { /BlueShift xdef }
  512.   43 { /BlueFuzz xdef }
  513.   10 { 1 array astore /StdHW xdef }
  514.   11 { 1 array astore /StdVW xdef }
  515.   44 { deltarray /StemSnapH xdef }
  516.   45 { deltarray /StemSnapV xdef }
  517.   46 { 0 ne /ForceBold xdef }
  518.   47 { /ForceBoldThreshold xdef }
  519.   48 { /lenIV xdef }
  520.   49 { /LanguageGroup xdef }
  521.   50 { /ExpansionFactor xdef }
  522.   51 { /initialRandomSeed xdef }
  523.   19 { PrivateStart add { readSubrs } offput }
  524.   20 { /defaultWidthX xdef }
  525.   21 { /nominalWidthX xdef }
  526.     % Multiple Master fonts only
  527.   59 { /NDV xdef }
  528.   60 { /CDV xdef }
  529.   61 { /lenBuildCharArray xdef }
  530. .dicttomark readonly def
  531.  
  532. /readPrivate {        % <font> <size> readPrivate -
  533.   2 dict begin
  534.   /PrivateStart pos def
  535.   f 3 1 roll exch 1 index f exch subfilefilter /f exch store
  536.   dup /FontType get exch
  537.   /Private get begin
  538.         % Default lenIV to -1 even for Type 1 CharStrings.
  539.   2 ne { /lenIV -1 def } if
  540.   //privatedictops Dict end
  541.   exch /f exch store advance
  542.   end
  543. } bind def
  544.  
  545. /readSubrs {        % <font> readSubrs -
  546.   /Subrs Index put
  547. } bind def
  548.  
  549. % ------ Main program ------ %
  550.  
  551. % Clean up after finishing a font.
  552. /cleanupFont {        % (currentdict) cleanupFont -
  553.         % Remove unwanted entries.
  554.   currentdict /charset undef
  555.   currentdict /CharStringArray undef
  556. } bind def
  557.  
  558. % Update the Encoding and CharStrings for a real font.
  559. /finishFont {        % (currentdict) finishFont -
  560.         % Construct the real Encoding.
  561.         % The value of Encoding is either a number, for predefined
  562.         % encodings, or an array of mixed GIDs and names.
  563.   /Encoding mark Encoding
  564.   DEBUG { (Encoding: ) print dup === flush } if
  565.   dup type /integertype eq {
  566.     StandardEncodings exch get { idname } forall
  567.   } {
  568.     {
  569.       dup type /integertype eq { charset exch get idname } if
  570.     } forall
  571.   } ifelse .packtomark def
  572.         % Construct the CharStrings.
  573.         % Note that they may only correspond to an initial
  574.         % subset of the charset.
  575.   /CharStrings charset length CharStringArray length .min dict def
  576.   DEBUG {
  577.     charset length =only ( charset ) print
  578.     CharStringArray length =only ( CharStringArray) =
  579.     charset == flush
  580.   } if
  581.   0 1 CharStrings maxlength 1 sub {
  582.     dup CharStringArray exch get
  583.     exch charset exch get idstring CharStrings xxput
  584.   } for
  585.   cleanupFont
  586. } bind def
  587.  
  588. % Replace CharStrings with GlyphDirectory for a CIDFont;
  589. % Move GlobalSubrs to descendent fonts.
  590. /finishCIDFont {    % (currentdict) finishCIDFont -
  591.         % Construct the GlyphDirectory, similar to CharStrings.
  592.   /FDBytes FDArray length 1 gt { 1 } { 0 } ifelse def
  593.   /GlyphDirectory charset length CharStringArray length .min dict def
  594.   DEBUG {
  595.     charset length =only ( charset ) print
  596.     CharStringArray length =only ( CharStringArray) =
  597.     charset == flush
  598.   } if
  599.   0 1 GlyphDirectory maxlength 1 sub {
  600.     dup CharStringArray exch get
  601.         % If there is more than one FDArray entry, add the font
  602.         % index to the beginning of each charstring.
  603.     FDBytes 1 eq {
  604.       FDSelect 2 index get
  605.       1 string dup 0 4 -1 roll put exch concatstrings
  606.     } if
  607.     exch charset exch get GlyphDirectory xxput
  608.   } for
  609.  
  610.   Private /GlobalSubrs .knownget {
  611.     FDArray {
  612.     /Private get /GlobalSubrs 2 index put
  613.     } forall
  614.     pop
  615.     Private /GlobalSubrs undef
  616.   } if
  617.  
  618.         % Clean up.
  619.   currentdict /FDSelect undef
  620.   cleanupFont
  621. } bind def
  622. % We need to pass the file as a parameter for the sake of the PDF
  623. % interpreter. Also for the sake of PDF, a flag forces the font
  624. % to be defined as <resname> instead of the name embedded in the data.
  625. % This is needed for subsetted fonts; it is valid if the CFF
  626. % contains only a single font.
  627. /StartData {          % <resname> <nbytes> StartData -
  628.   currentfile exch subfilefilter false ReadData
  629. } bind def
  630. /ReadData {           % <resname> <file> <forceresname> ReadData -
  631.  
  632.     % Initialize.
  633.  
  634.   30 dict begin
  635.   /forceresname exch def
  636.   /cff exch def
  637.   /pos 0 def
  638.   /resname exch cvlit def
  639.   /DEBUG DEBUG def    % bring the binding closer
  640.  
  641.     % Read the header.
  642.  
  643.   /f cff def
  644.   /vmajor next def
  645.   /vminor next def
  646.   /hdrsize next def
  647.   /aoffsize next def
  648.  
  649.     % Read the Indexes.
  650.  
  651.   /names Index def
  652.   /topdicts Index def
  653.   /strings Index def
  654.   /gsubrs Index def
  655.  
  656.     % Read the top Dicts.
  657.  
  658.   /offsets 50 dict def
  659.   /queued [] def
  660.   /opdict null def        % reserve a slot
  661.   /fonts [ topdicts {
  662.     0 () /SubFileDecode filter /f exch def
  663.     40 dict begin
  664.         % Preload defaults that differ from PostScript defaults,
  665.         % or that are required.
  666.       /FontType 2 def
  667.       /PaintType 0 def
  668.       /FontMatrix [0.001 0 0 0.001 0 0] def
  669.       /charset StandardCharsets 0 get def
  670.       /Encoding 0 def
  671.       /FontInfo 10 dict
  672.     dup /UnderlinePosition -100 put
  673.     dup /UnderlineThickness 50 put
  674.       def
  675.       /Private 20 dict
  676.     gsubrs length 0 ne { dup /GlobalSubrs gsubrs put } if
  677.       def
  678.       //topdictops Dict
  679.     currentdict end
  680.   } forall ] def
  681.  
  682.     % Read other tables with queued offsets.
  683.  
  684.   DEBUG { (offsets: ) print [ offsets { pop } forall ] == } if
  685.   { /f cff def
  686.     DEBUG { (pos=) print pos = } if
  687.     offsets pos 2 copy .knownget not { pop pop exit } if
  688.     3 1 roll undef
  689.     DEBUG { (exec queued: ) print dup == } if
  690.     exec
  691.   } loop
  692.   offsets length 0 ne {
  693.     (Error: missing tables at ) print [ offsets { pop } forall ] ==
  694.     (Current position is ) print pos ==
  695.     flush stop
  696.   } if
  697.  
  698.     % Process out-of-order tables.
  699.  
  700.   DEBUG { queued length =only ( queued) = flush } if
  701.   queued { exec } forall
  702.  
  703.     % Update Encoding and CharStrings.
  704.  
  705.   fonts {
  706.     begin
  707.     currentdict /CIDFontType known { finishCIDFont } { finishFont } ifelse
  708.     end
  709.   } forall
  710.  
  711.     % Wrap up.
  712.  
  713.   resname mark 0 1 fonts length 1 sub {
  714.     DEBUG { dup =only ( ) print flush } if
  715.     dup names exch get
  716.     forceresname { pop resname } if
  717.     DEBUG { dup == flush } if
  718.     exch fonts exch get
  719.     dup /CIDFontType known {
  720.         % This is a CIDFont.
  721.       dup /CIDFontName 3 index put
  722.       1 index exch /CIDFont defineresource
  723.     } {
  724.         % This is a font.
  725.       dup /FontName 3 index put
  726.       1 index exch definefont
  727.     } ifelse
  728.   } for .dicttomark
  729.   end        % temporary dict
  730.   end        % FontSetInit ProcSet
  731.   /FontSet defineresource pop
  732.  
  733. } bind def
  734.  
  735. % ---------------- Resource category definition ---------------- %
  736.  
  737. currentdict end readonly
  738.  
  739. languagelevel exch 2 .setlanguagelevel
  740.  
  741. /FontSet /Generic /Category findresource dup length dict .copydict
  742. /Category defineresource pop
  743.  
  744. /FontSetInit exch /ProcSet defineresource pop
  745.  
  746. .setlanguagelevel
  747.